package com.gmail.dmitryustimov.ms.java7.composite.mod.work.testperf;

import com.gmail.dmitryustimov.ms.java7.composite.mod.work.demo.structure1_6_9_6.*;
import com.gmail.dmitryustimov.ms.java7.patternslib.composite.Component;

import java.util.ArrayList;
import java.util.List;

public class TestPerf1_6_9_6 {

    private static final int NUM_WARM_UP = 3;
    private static final int NUM_TESTS = 100;

    private static final int NUM_ROOTS = 1;
    private static final int NUM_LEAFS_LEVEL1 = 3;
    private static final int NUM_COMPOSITES_LEVEL1 = 3;
    private static final int NUM_LEAFS_LEVEL2 = 2;
    private static final int NUM_COMPOSITES_LEVEL2 = 1;
    private static final int NUM_LEAFS_LEVEL3 = 2;

    private static final String MESSAGE = "composite_mod, 1-6-9-6, took: ";

    public static void main(String[] args) {

        //warm up
        for (int i = 0; i < NUM_WARM_UP; i++) {
            test();
        }

        //tests
        long time = 0;
        for (int j = 0; j < NUM_TESTS; j++) {
            time += test();
        }
        System.out.println("final - " + MESSAGE + time/NUM_TESTS + "ns (" + (time/NUM_TESTS)/1000000 + "ms)");
    }

    private static long test() {
        List<Component<Leaf>> structure = new ArrayList<>();

        for (int i = 1; i < NUM_ROOTS+1; i++) {
            Component<Leaf> root = new Composite<>("composite0" + i);
            structure.add(root);
            for (int k = 1; k < NUM_LEAFS_LEVEL1+1; k++) {
                root.add(new Leaf("leaf1" + k));
            }
            for (int h = 1; h < NUM_COMPOSITES_LEVEL1+1; h++) {
                Component<Leaf> composite1 = new Composite<>("composite1" + h);
                root.add(composite1);
                for (int j = 1; j < NUM_LEAFS_LEVEL2+1; j++) {
                    composite1.add(new Leaf("leaf2" + j));
                }
                for (int j = 1; j < NUM_COMPOSITES_LEVEL2+1; j++) {
                    Component<Leaf> composite2 = new Composite<>("composite2" + h);
                    composite1.add(composite2);
                    for (int f = 1; f < NUM_LEAFS_LEVEL3+1; f++) {
                        composite2.add(new Leaf("leaf3" + j));
                    }
                }
            }
        }

        long startTime = System.nanoTime();

        for (Component<Leaf> c: structure) {
            c.doAction();
        }

        long estimatedTime = System.nanoTime() - startTime;
        System.out.println(MESSAGE + estimatedTime + "ns");
        return estimatedTime;
    }
}
